import pygame
import random
import sys
from enum import Enum

class CellType(Enum):
    EMPTY = 0
    TYPE1 = 1
    TYPE2 = 2
    TYPE3 = 3
    TYPE4 = 4
    TYPE5 = 5
    TYPE6 = 6

class LianLianKan:
    def __init__(self, width=800, height=600):
        pygame.init()
        self.width = width
        self.height = height
        self.screen = pygame.display.set_mode((width, height))
        pygame.display.set_caption("连连看游戏")
        
        self.rows = 8
        self.cols = 10
        self.cell_size = 60
        self.board_offset_x = (width - self.cols * self.cell_size) // 2
        self.board_offset_y = (height - self.rows * self.cell_size) // 2
        
        self.board = [[CellType.EMPTY for _ in range(self.cols)] for _ in range(self.rows)]
        self.selected = []
        self.score = 0
        self.font = pygame.font.Font(None, 36)
        self.small_font = pygame.font.Font(None, 24)
        
        self.colors = {
            CellType.EMPTY: (240, 240, 240),
            CellType.TYPE1: (255, 100, 100),
            CellType.TYPE2: (100, 255, 100),
            CellType.TYPE3: (100, 100, 255),
            CellType.TYPE4: (255, 255, 100),
            CellType.TYPE5: (255, 100, 255),
            CellType.TYPE6: (100, 255, 255)
        }
        
        self.init_board()
        
    def init_board(self):
        types = []
        pairs_needed = (self.rows * self.cols) // 2
        
        for i in range(pairs_needed):
            cell_type = CellType(i % 6 + 1)
            types.extend([cell_type, cell_type])
        
        random.shuffle(types)
        
        for i in range(self.rows):
            for j in range(self.cols):
                if types:
                    self.board[i][j] = types.pop()
    
    def draw_board(self):
        self.screen.fill((255, 255, 255))
        
        for i in range(self.rows):
            for j in range(self.cols):
                x = self.board_offset_x + j * self.cell_size
                y = self.board_offset_y + i * self.cell_size
                
                color = self.colors[self.board[i][j]]
                pygame.draw.rect(self.screen, color, (x, y, self.cell_size, self.cell_size))
                
                if self.board[i][j] != CellType.EMPTY:
                    pygame.draw.rect(self.screen, (0, 0, 0), (x, y, self.cell_size, self.cell_size), 2)
                    
                    symbol = str(self.board[i][j].value)
                    text = self.font.render(symbol, True, (0, 0, 0))
                    text_rect = text.get_rect(center=(x + self.cell_size // 2, y + self.cell_size // 2))
                    self.screen.blit(text, text_rect)
                
                if (i, j) in self.selected:
                    pygame.draw.rect(self.screen, (255, 0, 0), (x, y, self.cell_size, self.cell_size), 4)
        
        score_text = self.small_font.render(f"分数: {self.score}", True, (0, 0, 0))
        self.screen.blit(score_text, (10, 10))
        
        if self.check_win():
            win_text = self.font.render("恭喜你赢了！", True, (255, 0, 0))
            win_rect = win_text.get_rect(center=(self.width // 2, 50))
            self.screen.blit(win_text, win_rect)
    
    def get_cell_from_pos(self, pos):
        x, y = pos
        col = (x - self.board_offset_x) // self.cell_size
        row = (y - self.board_offset_y) // self.cell_size
        
        if 0 <= row < self.rows and 0 <= col < self.cols:
            return (row, col)
        return None
    
    def can_connect(self, pos1, pos2):
        if pos1 == pos2:
            return False
        
        r1, c1 = pos1
        r2, c2 = pos2
        
        if self.board[r1][c1] == CellType.EMPTY or self.board[r2][c2] == CellType.EMPTY:
            return False
        
        if self.board[r1][c1] != self.board[r2][c2]:
            return False
        
        return self.find_path(pos1, pos2)
    
    def find_path(self, start, end):
        return (self.can_connect_directly(start, end) or
                self.can_connect_one_corner(start, end) or
                self.can_connect_two_corners(start, end))
    
    def can_connect_directly(self, start, end):
        r1, c1 = start
        r2, c2 = end
        
        if r1 == r2:
            step = 1 if c2 > c1 else -1
            for c in range(c1 + step, c2, step):
                if self.board[r1][c] != CellType.EMPTY:
                    return False
            return True
        
        if c1 == c2:
            step = 1 if r2 > r1 else -1
            for r in range(r1 + step, r2, step):
                if self.board[r][c1] != CellType.EMPTY:
                    return False
            return True
        
        return False
    
    def can_connect_one_corner(self, start, end):
        r1, c1 = start
        r2, c2 = end
        
        corner1 = (r1, c2)
        corner2 = (r2, c1)
        
        if (self.board[r1][c2] == CellType.EMPTY and
            self.can_connect_directly(start, corner1) and
            self.can_connect_directly(corner1, end)):
            return True
        
        if (self.board[r2][c1] == CellType.EMPTY and
            self.can_connect_directly(start, corner2) and
            self.can_connect_directly(corner2, end)):
            return True
        
        return False
    
    def can_connect_two_corners(self, start, end):
        r1, c1 = start
        r2, c2 = end
        
        for r in range(self.rows):
            if (self.board[r][c1] == CellType.EMPTY and
                self.board[r][c2] == CellType.EMPTY and
                self.can_connect_directly(start, (r, c1)) and
                self.can_connect_directly((r, c1), (r, c2)) and
                self.can_connect_directly((r, c2), end)):
                return True
        
        for c in range(self.cols):
            if (self.board[r1][c] == CellType.EMPTY and
                self.board[r2][c] == CellType.EMPTY and
                self.can_connect_directly(start, (r1, c)) and
                self.can_connect_directly((r1, c), (r2, c)) and
                self.can_connect_directly((r2, c), end)):
                return True
        
        return False
    
    def handle_click(self, pos):
        cell = self.get_cell_from_pos(pos)
        if not cell or self.board[cell[0]][cell[1]] == CellType.EMPTY:
            return
        
        if cell in self.selected:
            self.selected.remove(cell)
        else:
            self.selected.append(cell)
        
        if len(self.selected) == 2:
            if self.can_connect(self.selected[0], self.selected[1]):
                self.board[self.selected[0][0]][self.selected[0][1]] = CellType.EMPTY
                self.board[self.selected[1][0]][self.selected[1][1]] = CellType.EMPTY
                self.score += 10
            
            self.selected.clear()
    
    def check_win(self):
        for row in self.board:
            for cell in row:
                if cell != CellType.EMPTY:
                    return False
        return True
    
    def run(self):
        clock = pygame.time.Clock()
        running = True
        
        while running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
                elif event.type == pygame.MOUSEBUTTONDOWN:
                    if event.button == 1:
                        self.handle_click(event.pos)
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_r:
                        self.__init__(self.width, self.height)
            
            self.draw_board()
            pygame.display.flip()
            clock.tick(60)
        
        pygame.quit()
        sys.exit()

if __name__ == "__main__":
    game = LianLianKan()
    game.run()